package com.lib.common.helper.api.upload

import com.lib.common.api.ApiService
import com.lib.common.entity.api.resp.CosTokenResp
import com.lib.common.entity.api.resp.Credentials
import com.lib.common.helper.api.ApiHelper
import com.lib.common.helper.api.ApiResponse
import com.lib.common.helper.api.ComRequestCallback
import com.lib.framework.manager.LogManager
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
import com.tencent.cos.xml.listener.CosXmlResultListener
import com.tencent.cos.xml.model.CosXmlRequest
import com.tencent.cos.xml.model.CosXmlResult
import com.tencent.cos.xml.transfer.COSXMLUploadTask

/**
 * Copyright (C), 2020-2020, 享物说
 * FileName: UploadFile
 * Author: keanbin
 * Date: 2020-02-07 14:56
 * Description: 上传文件类
 * History:
 * <author> <time> <version> <desc>
 * 作者姓名 修改时间 版本号 描述
 */
class UploadFile() {

    /**
     * 上传任务
     */
    private var mCOSXMLUploadTask: COSXMLUploadTask? = null

    /**
     * 是否停止
     */
    private var mIsStop = true

    /**
     * 停止
     */
    fun stop() {
        mIsStop = true
        mCOSXMLUploadTask?.cancel()
    }

    /**
     * 上传文件
     */
    fun uploadFile(srcPath: String, l: CallBack) {
        mIsStop = false
        ApiHelper.getService(ApiService::class.java)?.cosToken()
            ?.request(object : ComRequestCallback<ApiResponse<CosTokenResp>>() {
                override fun onSuccess02(data: ApiResponse<CosTokenResp>?) {
                    LogManager.i(UploadHelper.TAG, "cosToken data = $data")
                    val credentials = data?.data?.credentials
                    if (credentials == null) {
                        l.onFail()
                        return
                    }

                    if (mIsStop) {
                        l.onCancel()
                        return
                    }

                    uploadFile(credentials, srcPath, l)
                }

                override fun onFailure(t: Throwable) {
                    LogManager.i(UploadHelper.TAG, "cosToken", t)
                    l.onFail()
                }
            })
    }

    /**
     * 上传文件
     */
    fun uploadFile(credentials: Credentials, srcPath: String, l: CallBack) {
        try {
            LogManager.d(UploadHelper.TAG, "start upload\t$srcPath")
            mCOSXMLUploadTask = UploadHelper.getCOSXMLUploadTask(credentials, srcPath)

            //返回结果回调
            mCOSXMLUploadTask?.setCosXmlResultListener(object : CosXmlResultListener {
                override fun onSuccess(request: CosXmlRequest?, result: CosXmlResult?) {
                    LogManager.d(UploadHelper.TAG, "success: url\t${result?.accessUrl}")

                    val fileUrl = result?.accessUrl
                    if (fileUrl.isNullOrEmpty()) {
                        l.onFail()
                    } else {
                        val cdnUrl = fileUrl.replace(Regex("http[s]?://[^/]*/"), "https://gogowa-cdn.xws.cn/")
                        l.onSuccess(cdnUrl)
                    }

                    QServiceCfg.instance().removeSrcPath(srcPath)
                }

                override fun onFail(
                    request: CosXmlRequest?,
                    exception: CosXmlClientException?,
                    serviceException: CosXmlServiceException?
                ) {
                    LogManager.d(
                        UploadHelper.TAG, "upload task failed: \t$srcPath," + if (exception == null)
                            serviceException?.message
                        else
                            exception.errorCode.toString() + "," + exception.message)

                    l.onFail()
                }
            })


            //上传进度回调
            mCOSXMLUploadTask?.setCosXmlProgressListener { complete, target ->
                val progress = (complete * 100 / target).toInt()
                LogManager.d(UploadHelper.TAG, "upload progress\t$progress\t" + Thread.currentThread().name)
                l.onProgress(complete, target)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 回调
     */
    interface CallBack {

        /**
         * 进度
         */
        fun onProgress(complete: Long, target: Long)

        /**
         * 成功
         */
        fun onSuccess(fileUrl: String?)

        /**
         * 失败
         */
        fun onFail()

        /**
         * 取消
         */
        fun onCancel()
    }
}